package cards;

import game.theGame;
import java.util.*;

// Referenced classes of package cards:
//            hand, card

public class HandLikelihood
{

    static boolean twoKind;
    static hand tempHand;

    public HandLikelihood()
    {
    }

    public static List handlikely(hand h, theGame g)
    {
        List returnlist = new ArrayList();
        if(g.currentHandType == 20)
        {
            List bl = h.findBomb();
            if(bl == null || bl.isEmpty())
            {
                return null;
            }
            bl = (List)bl.get(0);
            List al = new ArrayList();
            for(Iterator iterb = bl.iterator(); iterb.hasNext();)
            {
                List cl = (List)iterb.next();
                if(cl != null)
                {
                    al.add(cl.get(0));
                    al.add(cl.get(1));
                }
            }

            if(((card)al.get(al.size() - 1)).value > ((card)g.activeHand.get(g.activeHand.size() - 1)).value)
            {
                return al;
            }
            if(((card)al.get(al.size() - 1)).value == ((card)g.activeHand.get(g.activeHand.size() - 1)).value)
            {
                if(!compareSuits((card)al.get(al.size() - 1), (card)g.activeHand.get(g.activeHand.size() - 1)));
                return al;
            } else
            {
                return null;
            }
        }
        if(g.currentHandType == 1)
        {
            if(((card)g.activeHand.get(0)).value == 12 && !h.fourOfAKind.isEmpty())
            {
                return (List)h.fourOfAKind.get(0);
            }
            if(g.lowCardWarn() && !h.hasTwoHearts() || g.lowCardWarn2())
            {
                hand nextH;
                switch((h.playernumber + 1) % 4)
                {
                case 0: // '\0'
                    nextH = g.p1;
                    break;

                case 1: // '\001'
                    nextH = g.p2;
                    break;

                case 2: // '\002'
                    nextH = g.p3;
                    break;

                case 3: // '\003'
                    nextH = g.p0;
                    break;

                default:
                    nextH = null;
                    break;
                }
                if(nextH.theHand.size() == 1 || h.twos().size() > 1)
                {
                    List reverseHand = new ArrayList();
                    for(Iterator iter = h.theHand.iterator(); iter.hasNext(); reverseHand.add(0, iter.next())) { }
                    for(Iterator iter = reverseHand.iterator(); iter.hasNext();)
                    {
                        card c = (card)iter.next();
                        if(c.value > ((card)g.activeHand.get(0)).value)
                        {
                            returnlist.add(c);
                            return returnlist;
                        }
                        if(c.value == ((card)g.activeHand.get(0)).value && compareSuits(c, (card)g.activeHand.get(0)))
                        {
                            returnlist.add(c);
                            return returnlist;
                        }
                    }

                }
            }
            if(!h.freeSingles().isEmpty())
            {
                for(Iterator iter = h.freeSingles().iterator(); iter.hasNext();)
                {
                    card c = (card)iter.next();
                    if(c.value > ((card)g.activeHand.get(0)).value)
                    {
                        if(c.value != 12 || g.lowCardWarn())
                        {
                            returnlist.add(c);
                            return returnlist;
                        }
                    } else
                    if(c.value == ((card)g.activeHand.get(0)).value && compareSuits(c, (card)g.activeHand.get(0)))
                    {
                        returnlist.add(c);
                        return returnlist;
                    }
                }

            }
            if(!h.danglingSingles().isEmpty())
            {
                for(Iterator iter = h.danglingSingles().iterator(); iter.hasNext();)
                {
                    card c = (card)iter.next();
                    if(c.value > ((card)g.activeHand.get(0)).value)
                    {
                        returnlist.add(c);
                        return returnlist;
                    }
                    if(c.value == ((card)g.activeHand.get(0)).value && compareSuits(c, (card)g.activeHand.get(0)))
                    {
                        returnlist.add(c);
                        return returnlist;
                    }
                }

            }
            if(!h.straightExtra().isEmpty())
            {
                for(Iterator iter = h.straightExtra().iterator(); iter.hasNext();)
                {
                    card c = (card)iter.next();
                    if(c.value > ((card)g.activeHand.get(0)).value)
                    {
                        returnlist.add(c);
                        return returnlist;
                    }
                    if(c.value == ((card)g.activeHand.get(0)).value && compareSuits(c, (card)g.activeHand.get(0)))
                    {
                        returnlist.add(c);
                        return returnlist;
                    }
                }

            } else
            if(!h.twos().isEmpty() && h.maxPath() <= 2)
            {
                for(Iterator itert = h.twos().iterator(); itert.hasNext();)
                {
                    card d = (card)itert.next();
                    if(d.value > ((card)g.activeHand.get(0)).value)
                    {
                        returnlist.add(d);
                        return returnlist;
                    }
                    if(d.value == ((card)g.activeHand.get(0)).value && compareSuits(d, (card)g.activeHand.get(0)))
                    {
                        returnlist.add(d);
                        return returnlist;
                    }
                }

            } else
            {
                return null;
            }
        } else
        {
            if(g.currentHandType == 2)
            {
                int best = h.getHandValue(g);
                if(!h.pairs.isEmpty())
                {
                    for(Iterator iter = h.pairs.iterator(); iter.hasNext();)
                    {
                        List l = new ArrayList(h.theHand);
                        List k = (List)iter.next();
                        card c0 = (card)k.get(k.size() - 1);
                        card c1 = (card)g.activeHand.get(g.activeHand.size() - 1);
                        if(c0.value >= c1.value && (c0.value > c1.value || compareSuits(c0, c1)))
                        {
                            hand newHand = new hand(l, -1);
                            newHand.delHandFromHand(k);
                            if(newHand.getHandValue(g) > best)
                            {
                                best = newHand.getHandValue(g);
                                returnlist = k;
                            }
                        }
                    }

                    return returnlist;
                } else
                {
                    return null;
                }
            }
            if(g.currentHandType == 3)
            {
                int best = h.getHandValue(g);
                if(!h.triples.isEmpty())
                {
                    for(Iterator iter = h.triples.iterator(); iter.hasNext();)
                    {
                        List l = new ArrayList(h.theHand);
                        List k = (List)iter.next();
                        card c0 = (card)k.get(k.size() - 1);
                        card c1 = (card)g.activeHand.get(g.activeHand.size() - 1);
                        if(c0.value > c1.value)
                        {
                            hand newHand = new hand(l, -1);
                            newHand.delHandFromHand(k);
                            if(newHand.getHandValue(g) > best)
                            {
                                best = newHand.getHandValue(g);
                                returnlist = k;
                            }
                        }
                    }

                    return returnlist;
                } else
                {
                    return null;
                }
            }
            if(g.currentHandType == 4)
            {
                int best = h.getHandValue(g);
                if(!h.fourOfAKind.isEmpty())
                {
                    for(Iterator iter = h.fourOfAKind.iterator(); iter.hasNext();)
                    {
                        List l = new ArrayList(h.theHand);
                        List k = (List)iter.next();
                        card c0 = (card)k.get(k.size() - 1);
                        card c1 = (card)g.activeHand.get(g.activeHand.size() - 1);
                        if(c0.value > c1.value)
                        {
                            hand newHand = new hand(l, -1);
                            newHand.delHandFromHand(k);
                            if(newHand.getHandValue(g) > best)
                            {
                                best = newHand.getHandValue(g);
                                returnlist = k;
                            }
                        }
                    }

                    return returnlist;
                } else
                {
                    return null;
                }
            }
            if(g.currentHandType == 5)
            {
                return getMove(h, g, h.threeStraight);
            }
            if(g.currentHandType == 6)
            {
                return getMove(h, g, h.fourStraight);
            }
            if(g.currentHandType == 7)
            {
                return getMove(h, g, h.fiveStraight);
            }
            if(g.currentHandType == 8)
            {
                return getMove(h, g, h.sixStraight);
            }
            if(g.currentHandType == 9)
            {
                return getMove(h, g, h.sevenStraight);
            }
            if(g.currentHandType == 10)
            {
                return getMove(h, g, h.eightStraight);
            }
            if(g.currentHandType == 11)
            {
                return getMove(h, g, h.nineStraight);
            }
            if(g.currentHandType == 12)
            {
                return getMove(h, g, h.tenStraight);
            }
            if(g.currentHandType == 13)
            {
                return getMove(h, g, h.elevenStraight);
            }
            if(g.currentHandType == 13)
            {
                return getMove(h, g, h.twelveStraight);
            }
        }
        return null;
    }

    static List getMove(hand h, theGame g, List handList)
    {
        List returnlist = new ArrayList();
        int best = h.getHandValue(g);
        if(!handList.isEmpty())
        {
            for(Iterator iter = handList.iterator(); iter.hasNext();)
            {
                List l = new ArrayList(h.theHand);
                List j = (List)iter.next();
                List k = extractstraight(j);
                card c0 = (card)k.get(k.size() - 1);
                card c1 = (card)g.activeHand.get(g.activeHand.size() - 1);
                if(c0.value > c1.value)
                {
                    hand newHand = new hand(l, -1);
                    newHand.delHandFromHand(k);
                    if(newHand.getHandValue(g) > best)
                    {
                        best = newHand.getHandValue(g);
                        returnlist = k;
                    }
                }
            }

            if(returnlist.isEmpty())
            {
                return null;
            } else
            {
                return returnlist;
            }
        } else
        {
            return null;
        }
    }

    public static List controlLikely(hand h, theGame g)
    {
        List newHandList = new ArrayList();
        newHandList.addAll(h.theHand);
        tempHand = new hand(newHandList, -1);
        twoKind = (h.freeSingles().size() + h.danglingSingles().size()) - h.twos().size() < 0;
        boolean kind = true;
        List l = new ArrayList();
        int max = h.danglingSingles().size() + h.freeSingles().size() * 4 + h.twos().size() * 5;
        if(g.lowCardWarn())
        {
            if(h.theHand.size() == 2)
            {
                List countinghand = new ArrayList();
                countinghand.addAll(g.p0.theHand);
                countinghand.addAll(g.p1.theHand);
                countinghand.addAll(g.p2.theHand);
                countinghand.addAll(g.p3.theHand);
                hand totalhand = new hand(countinghand, -1);
                if(((card)totalhand.theHand.get(totalhand.theHand.size() - 1)).value == ((card)h.theHand.get(h.theHand.size() - 1)).value && ((card)totalhand.theHand.get(totalhand.theHand.size() - 1)).suit.equals(((card)h.theHand.get(h.theHand.size() - 1)).suit))
                {
                    l.add(h.theHand.get(h.theHand.size() - 1));
                } else
                {
                    l.add(h.theHand.get(0));
                }
            } else
            {
                int nextP = h.playernumber + 1;
                if(nextP == 4)
                {
                    nextP = 0;
                }
                hand nextH;
                switch(nextP)
                {
                case 0: // '\0'
                    nextH = g.p0;
                    break;

                case 1: // '\001'
                    nextH = g.p1;
                    break;

                case 2: // '\002'
                    nextH = g.p2;
                    break;

                case 3: // '\003'
                    nextH = g.p3;
                    break;

                default:
                    nextH = null;
                    break;
                }
                if(nextH.theHand.size() == 1 || h.twos().size() > 1)
                {
                    l.add(h.theHand.get(h.theHand.size() - 1));
                    max = 0;
                } else
                if(!h.freeSingles().isEmpty())
                {
                    l.add(h.freeSingles().get(0));
                }
            }
        } else
        if(!h.freeSingles().isEmpty())
        {
            l.add(h.freeSingles().get(0));
        }
        if(!l.isEmpty() && ((card)l.get(0)).value > 11 && h.maxPath() > 6 && h.maxPath() != h.theHand.size())
        {
            l = null;
            max = 0;
        }
        int tmp = selectionH(h.pairs, g, 2, 2);
        if(tmp >= max)
        {
            l = (List)h.pairs.get(0);
        }
        tmp = selectionH(h.triples, g, 3, 3);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.triples.get(0);
        }
        tmp = selectionH(h.fourOfAKind, g, 4, 4);
        if(tmp >= max && h.theHand.size() <= 5)
        {
            max = tmp;
            kind = true;
            l = (List)h.fourOfAKind.get(0);
        }
        tmp = selectionH(h.threeStraight, g, 3, 5);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.threeStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.fourStraight, g, 4, 6);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.fourStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.fiveStraight, g, 5, 7);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.fiveStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.sixStraight, g, 6, 8);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.sixStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.sevenStraight, g, 7, 9);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.sevenStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.eightStraight, g, 8, 10);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.eightStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.nineStraight, g, 9, 11);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.nineStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.tenStraight, g, 5, 7);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.tenStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.elevenStraight, g, 5, 7);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.elevenStraight.get(0);
            l = extractstraight(l);
        }
        tmp = selectionH(h.twelveStraight, g, 5, 7);
        if(tmp >= max)
        {
            max = tmp;
            kind = true;
            l = (List)h.twelveStraight.get(0);
            l = extractstraight(l);
        }
        if(!h.findBomb().isEmpty())
        {
            List bl = (List)h.findBomb().get(0);
            List al = new ArrayList();
            for(Iterator iterb = bl.iterator(); iterb.hasNext();)
            {
                List cl = (List)iterb.next();
                if(cl != null)
                {
                    al.add(cl.get(0));
                    al.add(cl.get(1));
                }
            }

            return al;
        } else
        {
            return l;
        }
    }

    public static int selectionH(List l, theGame g, int cardnums, int handtype)
    {
        if(l == null || l.isEmpty())
        {
            return -2;
        }
        List countinghand = new ArrayList();
        countinghand.addAll(g.p0.theHand);
        countinghand.addAll(g.p1.theHand);
        countinghand.addAll(g.p2.theHand);
        countinghand.addAll(g.p3.theHand);
        hand totalhand = new hand(countinghand, -1);
        int h = l.size() * cardnums;
        if(handtype > 4)
        {
            List w = (List)l.get(l.size() - 1);
            w = (List)w.get(w.size() - 1);
            card c = (card)w.get(w.size() - 1);
            w = (List)l.get(0);
            w = (List)w.get(0);
            card c2 = (card)w.get(0);
            if(c2.value < 6)
            {
                h += (6 - c2.value) * 10 * cardnums;
            }
            if(handtype == 5)
            {
                h += highAndLow(totalhand.threeStraight, c);
            } else
            if(handtype == 6)
            {
                h += highAndLow(totalhand.fourStraight, c);
            } else
            if(handtype == 7)
            {
                h += highAndLow(totalhand.fiveStraight, c);
            } else
            if(handtype == 8)
            {
                h += highAndLow(totalhand.sixStraight, c);
            } else
            if(handtype == 9)
            {
                h += highAndLow(totalhand.sevenStraight, c);
            } else
            if(handtype == 10)
            {
                h += highAndLow(totalhand.eightStraight, c);
            } else
            if(handtype == 11)
            {
                h += highAndLow(totalhand.nineStraight, c);
            } else
            if(handtype == 12)
            {
                h += highAndLow(totalhand.tenStraight, c);
            } else
            if(handtype == 13)
            {
                h += highAndLow(totalhand.elevenStraight, c);
            } else
            if(handtype == 14)
            {
                h += highAndLow(totalhand.twelveStraight, c);
            } else
            if(handtype == 15)
            {
                h += highAndLow(totalhand.thirteenStraight, c);
            }
        } else
        {
            List w = (List)l.get(l.size() - 1);
            card c = (card)w.get(w.size() - 1);
            w = (List)l.get(0);
            card c2 = (card)w.get(0);
            if(c2.value < 6)
            {
                h += (6 - c2.value) * 15 * cardnums;
            }
            if(c.value == 12 && !twoKind)
            {
                h -= 50;
            }
            if(handtype != 1)
            {
                if(handtype == 2)
                {
                    h += highAndLow2(totalhand.pairs, c);
                } else
                if(handtype == 3)
                {
                    h += highAndLow2(totalhand.triples, c);
                } else
                if(handtype == 4)
                {
                    h += highAndLow2(totalhand.fourOfAKind, c);
                    h -= 30;
                }
            }
        }
        return h;
    }

    static int highAndLow(List l, card c)
    {
        int value = 0;
        for(Iterator iter = l.iterator(); iter.hasNext();)
        {
            value++;
            List l2 = (List)iter.next();
            if(((List)l2.get(l2.size() - 1)).contains(c))
            {
                if(value == l.size())
                {
                    return 50;
                } else
                {
                    return (value / l.size()) * 25;
                }
            }
        }

        return value;
    }

    static int highAndLow2(List l, card c)
    {
        int value = 0;
        for(Iterator iter = l.iterator(); iter.hasNext();)
        {
            value++;
            List l2 = (List)iter.next();
            if(l2.contains(c))
            {
                if(value == l.size())
                {
                    return 50;
                } else
                {
                    return (value / l.size()) * 25;
                }
            }
        }

        return value;
    }

    static List extractstraight(List l)
    {
        List k = new ArrayList();
        List w;
        for(Iterator iter = l.iterator(); iter.hasNext(); k.add(w.get(w.size() - 1)))
        {
            w = (List)iter.next();
        }

        return k;
    }

    static boolean compareSuits(card c1, card c2)
    {
        if(c1.suit.equals("Hearts") || c2.suit.equals("Spades"))
        {
            return true;
        }
        if(c2.suit.equals("Hearts") || c1.suit.equals("Spades"))
        {
            return false;
        }
        if(c1.suit.equals("Clubs") && c2.suit.equals("Diamonds"))
        {
            return false;
        }
        return c1.suit.equals("Diamonds") && c2.suit.equals("Clubs");
    }

    static List dcCards(List l)
    {
        List nl = new ArrayList();
        card c0;
        for(Iterator iter = l.iterator(); iter.hasNext(); nl.add(c0))
        {
            card cneg1 = (card)iter.next();
            c0 = new card();
            c0.setValue(cneg1.value);
            c0.setSuit(cneg1.suit);
        }

        return nl;
    }
}
